import axios from "axios";
import router from "@/router";
import Element from "element-ui";
import store from '@/store';
import webConfig from '@/global.config'

// 自动获取当前环境的配置
export const BASE_URL = process.env.VUE_APP_BASE_URL;

const request = axios.create({
    baseURL: BASE_URL,
    timeout: 5 * 1000,
})

// 添加状态码常量
const ResponseCode = {
    SUCCESS: 20000,
    UNAUTHORIZED: 40100,
    TOKEN_EXPIRED: 40300
}

// 维护刷新 token 的状态
let isRefreshing = false;
// 存储待重试请求
let retryRequests = [];

// 请求拦截器
request.interceptors.request.use(
    config => {
        let whiteList = webConfig.whiteListApi;
        let url = config.url;
        let accessToken = store.state.accessToken;
        if (whiteList.indexOf(url) === -1 && accessToken) {
            // 为除白名单外的请求头添加token
            config.headers['Authorization'] = store.state.accessToken;
        }

        // return config是固定用法 必须有返回值
        return config;
    },
    error => {
        return Promise.reject(new Error(error));
    }
)


// 响应拦截器优化
request.interceptors.response.use(
    response => {
        const { data } = response;

        switch (data.code) {
            case ResponseCode.SUCCESS:
                return response;
                
            case ResponseCode.UNAUTHORIZED:
                Element.Message.error(data.message || '未授权');
                return response;

            case ResponseCode.TOKEN_EXPIRED:
                if (!store.state.refreshToken) {
                    localStorage.clear();
                    router.push({ path: "/login" });
                    Element.Message.error('登录已过期');
                    return response;
                }

                // 处理并发请求
                if (!isRefreshing) {
                    isRefreshing = true;
                    return refreshTokenAndRetry(response)
                        .then(token => {
                            // 执行队列中的请求
                            retryRequests.forEach(cb => cb(token));
                            retryRequests = [];
                            return request(response.config);
                        })
                        .catch(err => {
                            retryRequests = [];
                            localStorage.clear();
                            router.push({ path: "/login" });
                            return Promise.reject(err);
                        })
                        .finally(() => {
                            isRefreshing = false;
                        });
                }

                // 将请求加入队列
                return new Promise(resolve => {
                    retryRequests.push(token => {
                        response.config.headers['Authorization'] = token;
                        resolve(request(response.config));
                    });
                });

            default:
                const errorMsg = data.message || '系统异常';
                Element.Message.error(errorMsg);
                return response;
        }
    },
    error => {
        const message = getErrorMessage(error);
        Element.Message.error(message);
        return Promise.reject(error);
    }
);

/**
 * 刷新token方法
 * @returns 新token
 */
function refreshTokenAndRetry() {
    const refreshToken = store.state.refreshToken;
    return Promise.race([
        new Promise((_, reject) => setTimeout(() => reject(new Error('刷新token超时')), 5000)),
        request.create({ headers: { 'Authorization': refreshToken } })
            .get('/user/refreshToken?refreshToken=' + refreshToken)
            .then(res => {
                if (!res.data?.data !== ResponseCode.SUCCESS) {
                    Element.Message.error(res.data?.message);
                    // 清空vuex
                    localStorage.clear()
                    // 返回到登录页
                    router.push({ path: "/login" });
                } else {
                    store.commit('updateTokens', res.data.data);
                    return store.state.accessToken;
                }
            })
    ]);
}

// 统一的错误消息处理
function getErrorMessage(error) {
    if (error.response) {
        return error.response.data?.message || `请求错误(${error.response.status})`;
    }
    if (error.request) {
        return '网络异常，请检查连接';
    }
    return error.message || '未知错误';
}

export default request;
